package com.ecarx.vhaltests.hy11.testcases.climate;

import android.car.VehicleAreaWindow;
import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VhalUnitTestBase;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;


@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacElectricDefrosterOnTest extends VhalUnitTestBase {

    private static final String TAG = "HvacElectricDefrosterOnTest";
    private static boolean halValue;
    private static int halStatus;

    private static boolean halSecondValue;
    private static int halSecondStatus;

    private static int halArea;

    private static final int HVAC_ELECTRIC_DEFROSTER_ON = VehiclePropertyIds.HVAC_ELECTRIC_DEFROSTER_ON;


    private static final int SERVICE_ID_CLIMATE = 112;
    private static final int OP_ID_CLIMATE = 0xc8;


    final static Object lock = new Object();
    final static Object rearLock = new Object();

    @BeforeClass
    public static void testInit() {
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, HVAC_ELECTRIC_DEFROSTER_ON, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig(OP_ID_CLIMATE);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOnAvailable_02() {
        setHvacElectricDefrosterOnAvail(3, 0);
        testHvacElectricDefrosterOnAvailable(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, false);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOnAvailable_01() {
        setHvacElectricDefrosterOnAvail(1, 0);
        testHvacElectricDefrosterOnAvailable(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, true);
        delay();
    }


    @Test
    public void testHvacElectricDefrosterOnGet_01() {
        setHvacElectricDefrosterOnAvail(1, 0);
        testHvacElectricDefrosterOnGet(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, true);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOnGet_02() {
        setHvacElectricDefrosterOnAvail(1, 1);
        testHvacElectricDefrosterOnGet(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, false);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOnSet_01() {
        setHvacElectricDefrosterOnAvail(1, 0);
        testHvacElectricDefrosterOnSet(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, true);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOnSet_02() {
        setHvacElectricDefrosterOnAvail(1, 1);
        testHvacElectricDefrosterOnSet(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, false);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOn_Rear_Available_02() {
        setHvacElectricDefrosterOnRearAvail(3, 0);
        testHvacElectricDefrosterOnAvailable(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, false);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOn_Rear_Available_01() {
        setHvacElectricDefrosterOnRearAvail(1, 0);
        testHvacElectricDefrosterOnAvailable(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, true);
        delay();
    }


    @Test
    public void testHvacElectricDefrosterOn_Rear_Get_01() {
        setHvacElectricDefrosterOnRearAvail(1, 0);
        testHvacElectricDefrosterOnGet(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, true);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOn_Rear_Get_02() {
        setHvacElectricDefrosterOnRearAvail(1, 0);
        testHvacElectricDefrosterOnGet(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, false);
        delay();
    }


    @Test
    public void testHvacElectricDefrosterOn_Rear_Set_01() {
        setHvacElectricDefrosterOnRearAvail(1, 0);
        testHvacElectricDefrosterOnSet(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, true);
        delay();
    }

    @Test
    public void testHvacElectricDefrosterOn_Rear_Set_02() {
        setHvacElectricDefrosterOnRearAvail(1, 1);
        testHvacElectricDefrosterOnSet(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, false);
        delay();
    }

    private static CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                halArea = carPropertyValue.getAreaId();
                Log.d(TAG, "HVAC_ELECTRIC_DEFROSTER_ON onChangeEvent value: propertyId ：" + carPropertyValue.getPropertyId() + " propertyValue：" + carPropertyValue.getValue() + "");
                Log.d(TAG, "HVAC_ELECTRIC_DEFROSTER_ON onChangeEvent Status：" + carPropertyValue.getStatus());
                Log.d(TAG, "HVAC_ELECTRIC_DEFROSTER_ON onChangeEvent area：" + carPropertyValue.getAreaId());
                if (halArea == VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD) {
                    halValue = (boolean) carPropertyValue.getValue();
                    halStatus = carPropertyValue.getStatus();
                    synchronized (lock) {
                        lock.notify();
                    }
                } else if (halArea == VehicleAreaWindow.WINDOW_REAR_WINDSHIELD) {
                    halSecondValue = (boolean) carPropertyValue.getValue();
                    halSecondStatus = carPropertyValue.getStatus();

                    synchronized (rearLock) {
                        rearLock.notify();
                    }
                }
                Log.d(TAG, "HVAC_ELECTRIC_DEFROSTER_ON onChangeEvent halValue :" + halValue + " halSecondValue：" + halSecondValue);

            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {

        }
    };


    public void lockWait() {
        try {
            synchronized (lock) {
                lock.wait(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void secondLockWait() {
        try {
            synchronized (rearLock) {
                rearLock.wait(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public void testHvacElectricDefrosterOnAvailable(int area, boolean avail) {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(HVAC_ELECTRIC_DEFROSTER_ON, area);
        Log.d(TAG, "testHvacElectricDefrosterOnAvailable isAvail：" + isAvail);
        Assert.assertEquals(avail, isAvail);
    }

    public void testHvacElectricDefrosterOnSet(int area, boolean value) {
        Log.d(TAG, "testHvacElectricDefrosterOnSet area：" + area + " value: " + value);
        mCarPropertyMgr.setBooleanProperty(HVAC_ELECTRIC_DEFROSTER_ON, area, value);
        if (area == VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD) {
            lockWait();
            Assert.assertEquals(value, halValue);
        } else {
            secondLockWait();
            Assert.assertEquals(value, halSecondValue);
        }


    }

    public void testHvacElectricDefrosterOnGet(int area, boolean value) {
        Log.d(TAG, "testHvacElectricDefrosterOnGet area：" + area + " value: " + value);
        mCarPropertyMgr.setBooleanProperty(HVAC_ELECTRIC_DEFROSTER_ON, area, value);
        if (area == VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD) {
            lockWait();
        } else {
            secondLockWait();
        }

        boolean isHvacElectricDefrosterOn = mCarPropertyMgr.getBooleanProperty(HVAC_ELECTRIC_DEFROSTER_ON, area);
        Assert.assertEquals(value, isHvacElectricDefrosterOn);
    }

    public void setHvacElectricDefrosterOnAvail(int avail, int onOff) {
        Log.d(TAG, "setHvacElectricDefrosterOnAvail avail：" + avail);
        IpcpClient ipcpClient = new IpcpClient();
        String[] config_indexs = {"paclfrontdefrost.availability", "paclfrontdefrost.data"};
        int[] datas = {avail, onOff};
        boolean bb = ipcpClient.setClimaSignal(SERVICE_ID_CLIMATE, OP_ID_CLIMATE, config_indexs, datas);
        Assert.assertTrue(bb);
        lockWait();
    }


    public void setHvacElectricDefrosterOnRearAvail(int avail, int onOff) {
        Log.d(TAG, "setHvacElectricDefrosterOnRearAvail avail：" + avail);
        IpcpClient ipcpClient = new IpcpClient();
        String[] config_indexs = {"paclreardefrost.availability", "paclreardefrost.data"};
        int[] datas = {avail, onOff};
        boolean bb = ipcpClient.setClimaSignal(SERVICE_ID_CLIMATE, OP_ID_CLIMATE, config_indexs, datas);
        Assert.assertTrue(bb);
        secondLockWait();
    }


    private static void setConfig(int OperId) {
        IpcpClient ipcpClient = new IpcpClient();
        int climateOperId[] = {OperId};
        ipcpClient.setConfig(SERVICE_ID_CLIMATE, climateOperId);
    }

}
